import random
import pygame

from game_items import Enemy
from game_hub import  *
class Game(object):
    ''' 游戏类 '''
    def __init__(self):
        # 游戏窗口
        self.main_window = pygame.display.set_mode(SCREEN_RECT.size)
        pygame.display.set_caption("韩狗大战")
        # 游戏状态窗口
        self.is_game_over = False
        self.is_pause = False



        #精灵组属性
        self.all_group = pygame.sprite.Group()          #所有精灵组
        self.enemies_group = pygame.sprite.Group()      #敌对精灵组
        self.supplies_group = pygame.sprite.Group()     #道具精灵组


        #背景精灵,向下方移动
        # GameSprite("background.png",1,self.all_group)


        # #英雄精灵,静止不动
        # # hero = GameSprite(["me%d.png" % i for i in range(1,3)] ,self.all_group)
        # self.hero = Plane(1000,5,0,"me_down.wav",["me%d.png" % i for i in range(1,3)],"me1.png",["me_destroy_%d.png" %i for i in range(1,5)],self.all_group)
        # self.hero.rect.center = SCREEN_RECT.center           #显示在屏幕中间


        # 创建精灵
        # 背景精灵，交替滚动
        self.all_group.add(Background(False), Background(True))
        # 指示器面板
        self.hud_panel = HudPanel(self.all_group)
        # 创建敌机
        self.create_enemies()
        #英雄精灵
        self.hero = Hero(self.all_group)
        #设置面板中炸弹的数量
        self.hud_panel.show_bomb(self.hero.bomb_count)
        #TODO:将所有的敌机速度设置为0，并且修改敌机的初始位置
        for enemy in self.enemies_group.sprites():
            enemy.speed = 0
            enemy.rect.y += 400
        self.hero.speed = 1

    def check_collide(self):
        '''碰撞检测'''
        # 检测英雄飞机和敌机的碰撞,若英雄处于无敌状态，彼此不能相撞
        if not self.hero.is_power:
            enemies = pygame.sprite.spritecollide(self.hero,self.enemies_group,False,pygame.sprite.collide_mask())
            #过滤掉已经被摧毁的敌机
            enemies = list(filter(lambda x :x.hp >0,enemies))
            if enemies:
                self.hero.hp =0              #英雄被撞毁
            for enemy in enemies:
                enemy.hp = 0                #敌机被撞毁
        #检测敌机是否被子弹打中
        hit_enemies = pygame.sprite.groupcollide(self.enemies_group,self.hero.bullets_group,False,False,pygame.sprite.collide_mask)
        #遍历字典
        for enemy in hit_enemies:
            #已经被摧毁的敌机，不需要浪费子弹
            if enemy.hp<=0:
                continue
        #遍历击中敌机的子弹列表
        for bullet in hit_enemies[enemy]:
            #将子弹从所有精灵组移除
            bullet.kill()
            #修改敌机的生命值
            enemy.hp -= bullet.damage
            #如果敌机没有被摧毁，继续判定下一颗子弹
            if enemy.hp>0:
                continue
            #修改游戏得分并判断是否升级
            if self.hud_panel.increase_score(enemy.value):
                self.create_enemies()
            #退出遍历子弹列表的循环
            break


    def reset_game(self):
        '''  重置游戏 '''
        self.is_game_over = False
        self.is_pause = False
        self.hud_panel.reset_panel()
        self.hero.rect.midbottom= HERP_DEFAULT_MID_BOTTOM           #设置英雄飞机的初始位置
        #清空所有敌机
        for enemy in self.enemies_group:
            enemy.kill()
        #清空残留子弹
        for bullet in self.hero.bullets_group:
            bullet.kill()
        #重新创建敌机
        self.create_enemies()

    def create_enemies(self):
        """根据游戏级别创建不同数量的敌机"""

        # 敌机精灵组中的精灵数量
        count = len(self.enemies_group.sprites())
        # 要添加到的精灵组
        groups = (self.all_group, self.enemies_group)

        # 判断游戏级别及已有的敌机数量
        if self.hud_panel.level == 1 and count == 0:  # 关卡 1
            for i in range(16):
                Enemy(0,3,*groups)
        elif self.hud_panel.level == 2 and count == 16:  # 关卡 2
            # 1> 增加敌机的最大速度
            for enemy in self.enemies_group.sprites():
                enemy.max_speed = 5
            # 2> 创建敌机
            for i in range(8):
                Enemy(0,3,*groups)
            for i in range(2):
                Enemy(1, 1, *groups)
        elif self.hud_panel.level == 3 and count == 26:  # 关卡 3
            # 1> 增加敌机的最大速度
            for enemy in self.enemies_group.sprites():
                enemy.max_speed = 7 if enemy.kind == 0 else 3
            # 2> 创建敌机
            for i in range(8):
                Enemy(0, 7, *groups)
            for i in range(2):
                Enemy(1, 3, *groups)
            for i in range(2):
                Enemy(2, 1, *groups)


    def event_handler(self):
        '''事件监听
        :return:如果监听到退出事件,返回True,否则返回False
        '''
        for event in pygame.event.get():

            if event.type == pygame.QUIT:
                return True
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                return True
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
                if self.is_game_over:            #游戏已经结束
                    self.reset_game()               #重新开始游戏
                else:
                    self.is_pause = not self.is_pause       #切换暂停状态

            # 判断是否在游戏
            if not self.is_game_over and not self.is_pause:
                # 监听发射子弹事件
                if event.type == HERO_FIRE_EVENT:
                    self.hero.fire(self.all_group)


                # 监听取消英雄飞机无敌的事件
                if event.type == HERO_POWER_OFF_EVENT:
                    print('取消无敌状态')
                    # 设置英雄飞机状态
                    self.hero.is_power = False
                    # 取消定时器
                    pygame.time.set_timer(HERO_POWER_OFF_EVENT, 0)

                #监听英雄飞机牺牲事件
                if event.type == HERO_DEAD_EVENT:
                    print('你的机毁了...')
                    #生命-1
                    self.hud_panel.lives_count -=1
                    #更新生命计数显示
                    self.hud_panel.show_lives()
                    #更新炸弹显示
                    self.hud_panel.show_bomb(self.hero.bomb_count)


                # 监听玩家按下b键，引爆一颗炸弹
                if event.type == pygame.KEYDOWN and event.key == pygame.K_b:
                    #引爆炸弹
                    score = self.hero.blowup(self.enemies_group)
                    #更新炸弹数量显示
                    self.hud_panel.show_bomb(self.hero.bomb_count)
                    #更新游戏得分，若关卡等级提升，则可创建新的敌机机型
                    if self.hud_panel.increase_score(score):
                        self.create_enemies()
        return  False


    def start(self):
        ''' 开始游戏'''
        frame_counter = 0
        clock = pygame.time.Clock()                 #游戏时钟
        while True:
            #TODO模拟英雄飞机受到伤害
            self.hero.hp -=30
            #修改逐帧动画计数器
            frame_counter = (frame_counter+1) % FRAME_INTERVAL

            # 更新 all_group 中所有精灵内容
            # self.all_group.update()

            self.is_game_over =self.hud_panel.lives_count == 0
            if self.event_handler():                #事件监听
                self.hud_panel.save_best_score()
                return
            #判断游戏状态
            if self.is_game_over:
                self.hud_panel.panel_pause(True,self.all_group)

            elif self.is_pause:
                self.hud_panel.panel_pause(False,self.all_group)

            else:
                self.hud_panel.panel_resume(self.all_group)
                #碰撞检测
                self.check_collide()
                #获取当前时刻的按键元组
                keys = pygame.key.get_pressed()
                #判断是否按下右方向
                if keys[pygame.K_RIGHT]:
                    self.hero.rect.x += 10
                #水平移动基数
                move_hor = keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]
                #垂直移动基数
                move_ver = keys[pygame.K_DOWN] - keys[pygame.K_UP]

                #测试修改游戏得分
                # if self.hud_panel.increase_score(100):
                #     print("升级到 %d" %self.hud_panel.level)
                #     self.create_enemies()

                #修改逐帧动画计数器
                frame_counter =(frame_counter+1) % FRAME_INTERVAL
                # 更新 all_group 中所有精灵内容
                self.all_group.update(frame_counter == 0,move_hor,move_ver)


            # 绘制all_group中的精灵
            self.all_group.draw(self.main_window)
            pygame.display.update()                 #更新显示
            clock.tick(60)                          #设置刷新帧率

if __name__ == '__main__':
    pygame.init()
    Game().start()
    pygame.quit()